home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / ddj0492.zip / DFLT11.ZIP / SEARCH.C < prev    next >
Text File  |  1992-02-17  |  5KB  |  161 lines

  1. /* ---------------- search.c ------------- */
  2. #include "dflat.h"
  3.  
  4. extern DBOX SearchTextDB;
  5. extern DBOX ReplaceTextDB;
  6. static int CheckCase = TRUE;
  7.  
  8. /* - case-insensitive, white-space-normalized char compare - */
  9. static BOOL SearchCmp(int a, int b)
  10. {
  11.     if (b == '\n')
  12.         b = ' ';
  13.     if (CheckCase)
  14.         return a != b;
  15.     return tolower(a) != tolower(b);
  16. }
  17.  
  18. /* ----- replace a matching block of text ----- */
  19. static void replacetext(WINDOW wnd, char *cp1, DBOX *db)
  20. {
  21.     char *cr = GetEditBoxText(db, ID_REPLACEWITH);
  22.     char *cp = GetEditBoxText(db, ID_SEARCHFOR);
  23.     int oldlen = strlen(cp); /* length of text being replaced */
  24.     int newlen = strlen(cr); /* length of replacing text      */
  25.     int dif;
  26.     if (oldlen < newlen)    {
  27.         /* ---- new text expands text size ---- */
  28.         dif = newlen-oldlen;
  29.         if (wnd->textlen < strlen(wnd->text)+dif)    {
  30.             /* ---- need to reallocate the text buffer ---- */
  31.             int offset = (int)(cp1-wnd->text);
  32.             wnd->textlen += dif;
  33.             wnd->text = realloc(wnd->text, wnd->textlen+2);
  34.             if (wnd->text == NULL)
  35.                 return;
  36.             cp1 = wnd->text + offset;
  37.         }
  38.         memmove(cp1+dif, cp1, strlen(cp1)+1);
  39.     }
  40.     else if (oldlen > newlen)    {
  41.         /* ---- new text collapses text size ---- */
  42.         dif = oldlen-newlen;
  43.         memmove(cp1, cp1+dif, strlen(cp1)+1);
  44.     }
  45.     strncpy(cp1, cr, newlen);
  46. }
  47.  
  48. /* ------- search for the occurrance of a string ------- */
  49. static void SearchTextBox(WINDOW wnd, int Replacing, int incr)
  50. {
  51.     char *s1 = NULL, *s2, *cp1;
  52.     DBOX *db = Replacing ? &ReplaceTextDB : &SearchTextDB;
  53.     char *cp = GetEditBoxText(db, ID_SEARCHFOR);
  54.     BOOL rpl = TRUE, FoundOne = FALSE;
  55.  
  56.     while (rpl == TRUE && cp != NULL)    {
  57.         rpl = Replacing ?
  58.                 CheckBoxSetting(&ReplaceTextDB, ID_REPLACEALL) :
  59.                 FALSE;
  60.         if (TextBlockMarked(wnd))    {
  61.             ClearTextBlock(wnd);
  62.             SendMessage(wnd, PAINT, 0, 0);
  63.         }
  64.         /* search for a match starting at cursor position */
  65.         cp1 = CurrChar;
  66.         if (incr)
  67.             cp1++;    /* start past the last hit */
  68.         /* --- compare at each character position --- */
  69.         while (*cp1)    {
  70.             s1 = cp;
  71.             s2 = cp1;
  72.             while (*s1 && *s1 != '\n')    {
  73.                 if (SearchCmp(*s1, *s2))
  74.                     break;
  75.                 s1++, s2++;
  76.             }
  77.             if (*s1 == '\0' || *s1 == '\n')
  78.                 break;
  79.             cp1++;
  80.         }
  81.         if (s1 != NULL && (*s1 == 0 || *s1 == '\n'))    {
  82.             /* ----- match at *cp1 ------- */
  83.             FoundOne = TRUE;
  84.  
  85.             /* mark a block at beginning of matching text */
  86.             wnd->BlkEndLine = TextLineNumber(wnd, s2);
  87.             wnd->BlkBegLine = TextLineNumber(wnd, cp1);
  88.             if (wnd->BlkEndLine < wnd->BlkBegLine)
  89.                 wnd->BlkEndLine = wnd->BlkBegLine;
  90.             wnd->BlkEndCol =
  91.                 (int)(s2 - TextLine(wnd, wnd->BlkEndLine));
  92.             wnd->BlkBegCol =
  93.                 (int)(cp1 - TextLine(wnd, wnd->BlkBegLine));
  94.  
  95.             /* position the cursor at the matching text */
  96.             wnd->CurrCol = wnd->BlkBegCol;
  97.             wnd->CurrLine = wnd->BlkBegLine;
  98.             wnd->WndRow = wnd->CurrLine - wnd->wtop;
  99.  
  100.             /* align the window scroll to matching text */
  101.             if (WndCol > ClientWidth(wnd)-1)
  102.                 wnd->wleft = wnd->CurrCol;
  103.             if (wnd->WndRow > ClientHeight(wnd)-1)    {
  104.                 wnd->wtop = wnd->CurrLine;
  105.                 wnd->WndRow = 0;
  106.             }
  107.  
  108.             SendMessage(wnd, PAINT, 0, 0);
  109.             SendMessage(wnd, KEYBOARD_CURSOR,
  110.                 WndCol, wnd->WndRow);
  111.  
  112.             if (Replacing)    {
  113.                 if (rpl || YesNoBox("Replace the text?"))  {
  114.                     replacetext(wnd, cp1, db);
  115.                     wnd->TextChanged = TRUE;
  116.                     BuildTextPointers(wnd);
  117.                 }
  118.                 if (rpl)    {
  119.                     incr = TRUE;
  120.                     continue;
  121.                 }
  122.                 ClearTextBlock(wnd);
  123.                 SendMessage(wnd, PAINT, 0, 0);
  124.             }
  125.             return;
  126.         }
  127.         break;
  128.     }
  129.     if (!FoundOne)
  130.         MessageBox("Search/Replace Text", "No match found");
  131. }
  132.  
  133. /* ------- search for the occurrance of a string,
  134.         replace it with a specified string ------- */
  135. void ReplaceText(WINDOW wnd)
  136. {
  137.     if (CheckCase)
  138.         SetCheckBox(&ReplaceTextDB, ID_MATCHCASE);
  139.     if (DialogBox(wnd, &ReplaceTextDB, TRUE, NULL))    {
  140.         CheckCase=CheckBoxSetting(&ReplaceTextDB,ID_MATCHCASE);
  141.         SearchTextBox(wnd, TRUE, FALSE);
  142.     }
  143. }
  144.  
  145. /* ------- search for the first occurrance of a string ------ */
  146. void SearchText(WINDOW wnd)
  147. {
  148.     if (CheckCase)
  149.         SetCheckBox(&SearchTextDB, ID_MATCHCASE);
  150.     if (DialogBox(wnd, &SearchTextDB, TRUE, NULL))    {
  151.         CheckCase=CheckBoxSetting(&SearchTextDB,ID_MATCHCASE);
  152.         SearchTextBox(wnd, FALSE, FALSE);
  153.     }
  154. }
  155.  
  156. /* ------- search for the next occurrance of a string ------- */
  157. void SearchNext(WINDOW wnd)
  158. {
  159.     SearchTextBox(wnd, FALSE, TRUE);
  160. }
  161.